package com.zr.utils;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Calendar;
import java.util.concurrent.TimeUnit;

/**
 * 自动顺序生成唯一订单号工具类
 * @author huangguilong
 */
@Component
public class SequenceUtil {

    @Resource
    private RedisTemplate redisTemplate;

    private static final int DEFAULT_LENGTH = 3;

    /**
     * @Title: incr
     * @Description: 获取redis自增序号
     * @param key redis的 key值
     * @param delta 自增的增量
     * @return
     */
    public long incr(String key, long delta) {
        try {
            // 调用increment方法获取key的自增序号
            long l = redisTemplate.opsForValue().increment(key, delta);
            // 获取当前时间与凌晨时间差
            long time = getSecondsNextEarlyMorning();
            if (time > 0) {
                expire(key, time);
            }
            return l;
        } catch (Exception e) {
            return -1;
        }
    }

    /**
     * @Title: expire
     * @Description: 设置过期时间
     * @param key
     * @param time
     * @return
     */
    private boolean expire(String key, long time) {
        try {
            if (time > 0) {
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 将传入的数 seq 格式化成 length 位，不够前边补 0
     * 如果 length < 3 则按照 3 算
     * @param seq
     * @param length
     * @return
     */
    public static String getSequence(long seq, int length) {
        String str = String.valueOf(seq);
        int len = str.length();
        length = Math.max(length, DEFAULT_LENGTH);
        if (len >= length) {
            return str;
        }
        int rest = length - len;
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < rest; i++) {
            sb.append('0');
        }
        sb.append(str);
        return sb.toString();
    }

    /**
     * 获取当前时间与凌晨时间差，用于设置redis过期时间
     * @return
     */
    private Long getSecondsNextEarlyMorning() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DAY_OF_YEAR, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return (cal.getTimeInMillis() - System.currentTimeMillis()) / 1000;
    }
}


